extends Control

@onready var health_bar: ProgressBar = $HealthBar
@onready var health_label: Label = $HealthBar/HealthLabel
@onready var attack_button: Button = $AttackButton
@onready var move_joystick: Control = $MoveJoystick
@onready var attack_joystick: Control = $AttackJoystick
@onready var aim_overlay: Control = $AimOverlay
var soul_label: Label = null
var xp_bar: ProgressBar = null
var xp_text: Label = null
var level_right: Label = null
var health_right: Label = null
var energy_bar: ProgressBar = null
var energy_text: Label = null
var _displayed_health: float = 0.0
var energy_value_label: Label = null
var round_time_left: float = 5.0
var round_timer_label: Label = null
var wave_label: Label = null
var config_page: Control = null
var _round_waiting_collect: bool = false
var _round_cleared_enemies: bool = false
var _shop_open_scheduled: bool = false

var wave_index: int = 1

var player: PlayerController

func _ready():
	# 查找玩家
	player = get_tree().get_first_node_in_group("player")
	# 确保魂石计数标签存在
	soul_label = get_node_or_null("SoulLabel")
	if soul_label == null:
		soul_label = Label.new()
		soul_label.name = "SoulLabel"
		soul_label.text = "魂石: 0"
		add_child(soul_label)
	xp_bar = get_node_or_null("XPBar")
	if xp_bar == null:
		xp_bar = ProgressBar.new()
		xp_bar.name = "XPBar"
		xp_bar.min_value = 0
		xp_bar.max_value = 1
		xp_bar.value = 0
		xp_bar.size_flags_horizontal = Control.SIZE_EXPAND_FILL
		add_child(xp_bar)
	# 为经验条添加文字覆盖
	xp_text = xp_bar.get_node_or_null("XPText") if xp_bar else null
	if xp_bar and xp_text == null:
		xp_text = Label.new()
		xp_text.name = "XPText"
		xp_text.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
		xp_text.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
		xp_text.set_anchors_preset(Control.PRESET_FULL_RECT)
		xp_text.text = "0%"
		xp_bar.add_child(xp_text)
	# 经验条右侧等级
	level_right = get_node_or_null("LevelRight")
	if level_right == null:
		level_right = Label.new()
		level_right.name = "LevelRight"
		level_right.text = "等级:0"
		add_child(level_right)
		level_right.set_anchors_preset(Control.PRESET_TOP_LEFT)
		level_right.position = Vector2(235, 28)
	# 生命条右侧仅显示回复
	health_right = get_node_or_null("HealthRight")
	if health_right == null:
		health_right = Label.new()
		health_right.name = "HealthRight"
		health_right.text = "+0.0/s"
		add_child(health_right)
		health_right.set_anchors_preset(Control.PRESET_TOP_LEFT)
		health_right.position = Vector2(235, 6)
	# 细蓝条（能量）
	energy_bar = get_node_or_null("EnergyBar")
	if energy_bar == null:
		energy_bar = ProgressBar.new()
		energy_bar.name = "EnergyBar"
		add_child(energy_bar)
		energy_bar.set_anchors_preset(Control.PRESET_TOP_LEFT)
		energy_bar.position = Vector2(10, 48)
		energy_bar.set_deferred("size", Vector2(220, 12))
		energy_bar.show_percentage = false
		var bg := StyleBoxFlat.new()
		bg.bg_color = Color(0.1, 0.2, 0.35, 0.9)
		bg.corner_radius_top_left = 3
		bg.corner_radius_top_right = 3
		bg.corner_radius_bottom_left = 3
		bg.corner_radius_bottom_right = 3
		var fg := StyleBoxFlat.new()
		fg.bg_color = Color(0.3, 0.6, 1.0, 1.0)
		fg.corner_radius_top_left = 3
		fg.corner_radius_top_right = 3
		fg.corner_radius_bottom_left = 3
		fg.corner_radius_bottom_right = 3
		energy_bar.add_theme_stylebox_override("background", bg)
		energy_bar.add_theme_stylebox_override("fill", fg)
		# 能量条内部数值
		energy_value_label = Label.new()
		energy_value_label.name = "EnergyValue"
		energy_value_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
		energy_value_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
		energy_value_label.set_anchors_preset(Control.PRESET_FULL_RECT)
		energy_value_label.add_theme_color_override("font_color", Color(1,1,1,0.95))
		energy_value_label.add_theme_font_size_override("font_size", 10)
		energy_value_label.text = "0/0"
		energy_bar.add_child(energy_value_label)
	else:
		energy_value_label = energy_bar.get_node_or_null("EnergyValue")
	# 能量条右侧文本
	energy_text = get_node_or_null("EnergyText")
	if energy_text == null:
		energy_text = Label.new()
		energy_text.name = "EnergyText"
		energy_text.text = "+0.0/s"
		add_child(energy_text)
		energy_text.set_anchors_preset(Control.PRESET_TOP_LEFT)
		energy_text.position = Vector2(235, 44)

	# 持久化布局已在 tscn 设置，这里不再覆盖
	
	# 连接攻击按钮信号
	attack_button.pressed.connect(_on_attack_button_pressed)
	
	# 连接摇杆信号
	if move_joystick:
		move_joystick.joystick_moved.connect(_on_move_joystick_moved)
		move_joystick.joystick_released.connect(_on_move_joystick_released)
	
	if attack_joystick:
		attack_joystick.attack_direction.connect(_on_attack_joystick_moved)
		attack_joystick.attack_ended.connect(_on_attack_joystick_released)
	
	# 初始化UI
	if player:
		update_health_display(player.get_current_health())
	else:
		update_health_display(0)
	# 进度条仅作为底层条，不显示内置数字
	if health_bar:
		health_bar.show_percentage = false
	if xp_bar:
		xp_bar.show_percentage = false
	if player:
		player.soul_count_changed.connect(_on_soul_count_changed)
		player.xp_changed.connect(_on_xp_changed)
		_on_soul_count_changed(player.soul_count)
		_on_xp_changed(player.xp, player.get_required_xp_for_level(player.level))
		_update_right_texts()
	# 倒计时标签
	round_timer_label = get_node_or_null("RoundTimerLabel")
	if round_timer_label == null:
		round_timer_label = Label.new()
		round_timer_label.name = "RoundTimerLabel"
		round_timer_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
		round_timer_label.set_anchors_preset(Control.PRESET_TOP_WIDE)
		round_timer_label.position = Vector2(0, 4)
		add_child(round_timer_label)
	# 波次标签
	wave_label = get_node_or_null("WaveLabel")
	if wave_label == null:
		wave_label = Label.new()
		wave_label.name = "WaveLabel"
		wave_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
		wave_label.set_anchors_preset(Control.PRESET_TOP_WIDE)
		wave_label.position = Vector2(0, 22)
		wave_label.add_theme_font_size_override("font_size", 16)
		add_child(wave_label)
	_update_wave_label()
	_update_round_timer_label()
	# 配置页面
	config_page = get_node_or_null("ConfigPage")
	# 启动时确保默认连接（第一波可射击）
	var graph_start := config_page.get_node_or_null("Graph") if config_page else null
	if graph_start and graph_start.has_method("ensure_default_connection"):
		# 延迟调用，确保所有节点都已初始化
		call_deferred("_ensure_default_connection_deferred", graph_start)

func _ensure_default_connection_deferred(graph: Node):
	# 延迟确保默认连接，只在根节点没有任何连接时创建
	if graph and graph.has_method("ensure_default_connection"):
		graph.call("ensure_default_connection")

func _process(_delta):
	if player:
		# 更新攻击按钮冷却显示
		var cooldown_progress = player.get_attack_cooldown_progress()
		attack_button.modulate = Color.WHITE if cooldown_progress >= 1.0 else Color.GRAY
		
		# 更新生命值显示
		# 平滑生命条：缓动到目标生命值
		var target_health := float(player.get_current_health())
		if _displayed_health == 0.0:
			_displayed_health = target_health
		var lerp_speed := 6.0
		_displayed_health = lerp(_displayed_health, target_health, clamp(get_process_delta_time() * lerp_speed, 0.0, 1.0))
		update_health_display(_displayed_health)
		# 同步能量条
		_update_right_texts()
		# 倒计时
		round_time_left = max(0.0, round_time_left - _delta)
		_update_round_timer_label()
		if round_time_left <= 0.0:
			# 主动关闭地板刷怪
			var floor_node := get_tree().current_scene.get_node_or_null("Floor")
			if floor_node and floor_node.has_method("set_spawning_enabled"):
				floor_node.set_spawning_enabled(false)
			# 先清空所有敌人
			if not _round_cleared_enemies:
				_clear_all_enemies()
				_round_cleared_enemies = true
			# 然后进行全图拾取
			if not _round_waiting_collect:
				_auto_collect_all_souls()
				_round_waiting_collect = true
			# 等魂石清空后再入商店
			if config_page and not config_page.visible:
				var stones := get_tree().get_nodes_in_group("soul_stone")
				if stones.is_empty():
					# 等待0.5秒再进入商店页面，保证拾取动画播放完成
					if not _shop_open_scheduled:
						_shop_open_scheduled = true
						var timer := get_tree().create_timer(0.5)
						timer.timeout.connect(func():
							if config_page and not config_page.visible:
								config_page.visible = true
								get_tree().paused = true
								# 在每一波结束后添加节点到仓库并刷新商店
								print("[GameUI] 第", wave_index, "波结束，准备添加节点到仓库并刷新商店")
								
								# 添加节点到仓库
								if wave_index == 1:
									# 添加一个重型子弹修饰节点
									add_node_to_warehouse("heavy_bullet")
									# 添加一个基础子弹攻击节点
									add_node_to_warehouse("basic_bullet")
								
								# 刷新商店
								_refresh_shop()
						)
		# 魂石计数实时刷新由信号驱动，这里无需每帧更新

func update_health_display(health: float):
	if player and health_bar:
		health_bar.max_value = float(player.max_health)
		health_bar.value = health
	# 标签仍然显示为整数
	health_label.text = "生命值: " + str(int(round(health)))

func _on_soul_count_changed(value: int) -> void:
	if soul_label:
		soul_label.text = "魂石: " + str(value)

func _on_xp_changed(current: int, required: int) -> void:
	if xp_bar:
		xp_bar.max_value = max(1, required)
		xp_bar.value = clamp(current, 0, required)
	if xp_text and player:
		var percent := 0
		if required > 0:
			percent = int(floor(100.0 * float(current) / float(required)))
		xp_text.text = str(percent) + "%"
	if level_right and player:
		level_right.text = "等级:" + str(player.level)
	_update_right_texts()

func _update_right_texts() -> void:
	if player:
		if health_right:
			health_right.text = "+" + str(snapped(player.get_health_regen_per_sec(), 0.01)) + "/s"
		if energy_bar:
			energy_bar.max_value = player.energy_max
			energy_bar.value = player.energy
			if energy_value_label:
				energy_value_label.text = str(int(player.energy)) + "/" + str(player.energy_max)
		if energy_text:
			energy_text.text = "+" + str(snapped(player.get_energy_regen_per_sec(), 0.01)) + "/s"

func _on_attack_button_pressed():
	if player and player.can_attack():
		# 触发玩家攻击（检查冷却时间）
		player.attack()

## 移动摇杆信号处理
func _on_move_joystick_moved(direction: Vector2):
	if player:
		player.set_joystick_input(direction)

func _on_move_joystick_released():
	if player:
		player.set_joystick_input(Vector2.ZERO)

## 攻击摇杆信号处理
func _on_attack_joystick_moved(direction: Vector2):
	if player:
		player.set_attack_joystick_direction(direction)
		# 持续攻击（但由player.attack()内部验证节点配置）
		if player.can_attack():
			player.attack()
		# 显示瞄准可视化（仅方向非零）
		var info = player.get_bullet_spread_info()
		var spread_deg = float(info["spread_deg"]) if info.has("spread_deg") else 0.0
		if direction.length() > 0.1:
			if aim_overlay and aim_overlay.has_method("show_aim"):
				aim_overlay.call("show_aim", direction.normalized(), spread_deg)
		else:
			if aim_overlay and aim_overlay.has_method("hide_aim"):
				aim_overlay.call("hide_aim")

func _on_attack_joystick_released():
	if player:
		player.set_attack_joystick_direction(Vector2.ZERO)  # 使用零方向触发自动预判
		if aim_overlay and aim_overlay.has_method("hide_aim"):
			aim_overlay.call("hide_aim")

func _update_round_timer_label() -> void:
	if round_timer_label:
		round_timer_label.text = str(int(ceil(round_time_left)))

func _update_wave_label() -> void:
	if wave_label:
		wave_label.text = "第" + str(wave_index) + "波"

func _auto_collect_all_souls() -> void:
	# 遍历所有魂石，改为强制磁吸，碰到玩家再拾取
	var stones = get_tree().get_nodes_in_group("soul_stone")
	for s in stones:
		if not s or not player:
			continue
		if s.has_method("force_magnet_to"):
			s.force_magnet_to(player)

func _clear_all_enemies() -> void:
	# 清空所有敌人且不掉落魂石：优先调用安全销毁接口
	var enemies = get_tree().get_nodes_in_group("enemy")
	for e in enemies:
		if not e:
			continue
		# 如果有自定义死亡逻辑，跳过掉落并直接移除
		if e.has_method("queue_free"):
			# 若敌人有信号或Tween，直接移除即可；避免调用 die()
			e.queue_free()

# === 配置页按钮钩子 ===
func go_next_stage() -> void:
	print("[GameUI] go_next_stage() 被调用，当前 wave_index = ", wave_index)
	
	# 关闭配置页，开始下一波
	if config_page:
		config_page.visible = false
	get_tree().paused = false
	wave_index += 1
	_update_wave_label()
	
	# 重置回合状态与计时
	_round_waiting_collect = false
	_round_cleared_enemies = false
	_shop_open_scheduled = false
	round_time_left = 35.0
	_update_round_timer_label()
	# 重新开启刷怪
	var floor_node := get_tree().current_scene.get_node_or_null("Floor")
	if floor_node and floor_node.has_method("set_spawning_enabled"):
		floor_node.set_spawning_enabled(true)

func refresh_shop() -> void:
	# 预留：刷新商店内容的逻辑
	print("[Shop] 刷新商店（待实现具体内容）")

# 刷新商店（内部调用）
func _refresh_shop() -> void:
	# 获取配置图表的引用
	var graph := config_page.get_node_or_null("Graph") if config_page else null
	if graph and graph.has_method("_refresh_shop_items"):
		graph.call("_refresh_shop_items")
		print("[GameUI] 已刷新商店")
	else:
		print("[GameUI] 无法找到配置图表或商店刷新方法")

# 通用函数：添加指定ID的节点到玩家仓库
func add_node_to_warehouse(node_id: String) -> bool:
	print("[GameUI] add_node_to_warehouse() 开始执行，节点ID: ", node_id)
	
	# 获取配置图表的引用
	var graph := config_page.get_node_or_null("Graph") if config_page else null
	if not graph or not graph.has_method("_append_warehouse_entry"):
		print("[GameUI] 无法找到配置图表或仓库添加方法")
		return false
	
	# 获取节点仓库
	var node_repository = get_tree().get_first_node_in_group("node_repository")
	if not node_repository:
		node_repository = get_tree().get_node_or_null("NodeRepository")
	
	if not node_repository:
		print("[GameUI] 无法找到节点仓库")
		return false
	
	# 获取指定ID的节点数据
	var node_data = node_repository.get_node_by_id(node_id)
	if not node_data:
		print("[GameUI] 节点仓库中找不到ID为 '", node_id, "' 的节点")
		return false
	
	# 延迟添加，确保在仓库填充完成后执行（短延迟）
	var timer := get_tree().create_timer(0.1)
	timer.timeout.connect(func():
		_add_node_to_warehouse_deferred(graph, node_data)
	)
	return true

# 延迟添加节点到仓库
func _add_node_to_warehouse_deferred(graph, node_data) -> void:
	print("[GameUI] 开始延迟添加节点到仓库：", node_data.name)
	
	# 创建节点
	var ni = graph.NodeItem.new()
	ni.id = node_data.id
	ni.name = node_data.name
	ni.node_type = node_data.node_type
	ni.is_root = false
	
	print("[GameUI] 创建节点：ID=", ni.id, ", 名称=", ni.name, ", 类型=", ni.node_type)
	
	# 加载图标
	if ResourceLoader.exists(node_data.icon_path):
		ni.icon = load(node_data.icon_path)
		print("[GameUI] 成功加载图标：", node_data.icon_path)
	else:
		print("[GameUI] 警告：找不到图标文件：", node_data.icon_path)
		return
	
	# 添加到仓库
	graph._append_warehouse_entry(ni)
	print("[GameUI] 已添加节点到仓库：", ni.name)


# 添加重型子弹节点到仓库（保持向后兼容）
func _add_heavy_bullet_to_warehouse() -> void:
	add_node_to_warehouse("heavy_bullet")
